package com.bright.hxj.cwduijie.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.bright.ghj.common.util.AssertUtil;
import com.bright.ghj.common.util.DateUtil;
import com.bright.ghj.common.util.StringUtil;
import com.bright.hxj.cwduijie.constant.ConfigConstants;
import com.bright.hxj.cwduijie.constant.SystemConstants;
import com.bright.hxj.cwduijie.converter.*;
import com.bright.hxj.cwduijie.enums.DataApi;
import com.bright.hxj.cwduijie.enums.OpType;
import com.bright.hxj.cwduijie.enums.SJJHBZ;
import com.bright.hxj.cwduijie.manager.DataManager;
import com.bright.hxj.cwduijie.manager.DuijieManager;
import com.bright.hxj.cwduijie.pojo.bo.ApiDataCollection;
import com.bright.hxj.cwduijie.pojo.command.*;
import com.bright.hxj.cwduijie.pojo.dto.*;
import com.bright.hxj.cwduijie.pojo.po.*;
import com.bright.hxj.cwduijie.pojo.query.DuijieQuery;
import com.bright.hxj.cwduijie.pojo.vo.*;
import com.bright.hxj.cwduijie.service.*;
import com.bright.hxj.cwduijie.util.CommonUtil;
import com.bright.hxj.cwduijie.util.EntityManagerUtil;
import com.bright.ghj.common.util.ListUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.EntityManager;
import java.io.IOException;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author hxj
 * @Date 2024/7/24 10:57
 * @Description
 */

@Component
@RequiredArgsConstructor
@Slf4j
public class DataBusiness {

    private final DataManager dataManager;
    private final DuijieManager duijieManager;
    private final ObjectMapper objectMapper;

    @Qualifier("normal")
    private final WebExchangeService webExchangeService;
    @Qualifier("testSend")
    private final WebExchangeService testSendwebExchangeService;
    private final ConfigConstants constants;
    private final EntityManager entityManager;
    private final ApiServiceFactory factory;

    // 批量对接 一千条一次
    public void sendAccSetDataPerThousand(List<String> dataKeys) throws JsonProcessingException {
//        DuijieQuery duijieQuery = new DuijieQuery();
//        duijieQuery.setZtDataKeys(dataKeys);
        List<AccSet> accSetsByDataKeys = new ArrayList<>();

        int count = 0;

        //分批查询
        while (count < dataKeys.size()) {

            DuijieQuery duijieQuery = new DuijieQuery();
            List<String> subList = ListUtil.getSubList(dataKeys, count, count + 1000);
            duijieQuery.setZtDataKeys(subList);
            accSetsByDataKeys.addAll(dataManager.getAccSetsByDataKeys(duijieQuery));
            count += 1000;
        }

//        List<AccSet> accSetsByDataKeys = dataManager.getAccSetsByDataKeys(duijieQuery);
//        if (isAllDataExecuting(DataApi.ACC_SET, accSetsByDataKeys, AccSet::getSjjhbz)) return;
        // 过滤出需要对接或上次推送异常的数据
        List<AccSet> accSets = ListUtil.toListByFilter(accSetsByDataKeys, accSet -> accSet.getSjjhbz() == SJJHBZ.WAITING.getValue() || accSet.getSjjhbz() == SJJHBZ.ERROR.getValue());

//        sendDataPerThousand(DataApi.ACC_SET, accSets, AccSet::getId, null, null);

    }

    /**
     * 20240720 判断是否所有数据都在排队中 如果都在排队 则该次对接不推送 以免重复排队
     */
    private <T> boolean isAllDataExecuting(DataApi dataApi, List<T> listData, Function<T, Integer> getSjjhbzFunc) {
        if (listData.size() == 0) {
            return false;
        }
        for (T eachData : listData) {
            Integer sjjhbz = getSjjhbzFunc.apply(eachData);
            if (sjjhbz != SJJHBZ.EXECUTING.getValue()) {
                return false;
            }
        }

        // TODO 保存该次结果为排队中


//        List<SaveTaskIdCommand> saveTaskIdCommands = new ArrayList<>();
//        saveTaskIdAndSaveSendDataResult(saveTaskIdCommands, null, null, SJJHBZ.EXECUTING.getValue(),
//                dataApi.getServiceCode(), dataApi, "已在推送中，本次不重复推送", null);

        return true;
    }

    /**
     * 获取哪些账套有数据需要对接 返回的ZT_DATA_KEY
     * @param duijieCommand 对接命令
     * @param needDuijieApis 要检查哪些接口
     * @return
     */
    public List<String> getNeedDuijieAccSetsByDuijieCommand(DuijieCommand duijieCommand, List<AbstractApiService<?>> needDuijieApis) {
        List<String> needDuijieZtDataKeys = new ArrayList<>();
        for (AbstractApiService<?> needDuijieApi : needDuijieApis) {
            needDuijieZtDataKeys.addAll(needDuijieApi.getNeedDuijieZtDataKeys(duijieCommand));
        }

        if (ListUtil.isNotEmpty(duijieCommand.getAccSets())) {
            // 如果有指定要对哪些账套 就根据这个来（改成在需要对接的账套里筛选）
            List<Object> accSets = duijieCommand.getAccSets();
            // 把账套号转换成统一社会信用代码 最后再拿到账套的data_key
            List<String> selectedZtDataKeys = dataManager.getZtDataKeyByAccSets(accSets);
            // 上面拿到了传参指定的账套data_key 然后判断一下哪些账套是有数据需要对接的
            List<String> resultZtDataKeys = new ArrayList<>();
            for (String selectedZtDataKey : selectedZtDataKeys) {
                if (needDuijieZtDataKeys.contains(selectedZtDataKey)) {
                    resultZtDataKeys.add(selectedZtDataKey);
                }
            }
            needDuijieZtDataKeys = resultZtDataKeys;
        }
        // 增加去重处理
        needDuijieZtDataKeys = needDuijieZtDataKeys.stream().distinct().collect(Collectors.toList());
        return needDuijieZtDataKeys;
    }

    /**
     * 获取哪些账套有数据需要对接 返回的是信用代码
     * @param duijieCommand 对接命令
     * @param needDuijieApis 要检查哪些接口
     * @return
     */
    public List<String> getNeedDuijieCreditCodesByDuijieCommand(DuijieCommand duijieCommand, List<AbstractApiService<?>> needDuijieApis) {
        List<String> needDuijieZtDataKeys = new ArrayList<>();
        for (AbstractApiService<?> needDuijieApi : needDuijieApis) {
            needDuijieZtDataKeys.addAll(needDuijieApi.getNeedDuijieZtDataKeys(duijieCommand));
        }

        if (ListUtil.isNotEmpty(duijieCommand.getAccSets())) {
            // 如果有指定要对哪些账套 就根据这个来（改成在需要对接的账套里筛选）
            List<Object> accSets = duijieCommand.getAccSets();
            // 把账套号转换成统一社会信用代码 最后再拿到账套的data_key
            List<String> selectedZtDataKeys = dataManager.getZtDataKeyByAccSets(accSets);
            // 上面拿到了传参指定的账套data_key 然后判断一下哪些账套是有数据需要对接的
            List<String> resultZtDataKeys = new ArrayList<>();
            for (String selectedZtDataKey : selectedZtDataKeys) {
                if (needDuijieZtDataKeys.contains(selectedZtDataKey)) {
                    resultZtDataKeys.add(selectedZtDataKey);
                }
            }
            needDuijieZtDataKeys = resultZtDataKeys;
        }
        // 增加去重处理
        needDuijieZtDataKeys = needDuijieZtDataKeys.stream().distinct().collect(Collectors.toList());
        return needDuijieZtDataKeys;
    }

    // 只对接传入的账套 按批次
    public void duijieByAccSet(DuijieCommand duijieCommand, String needDuijieZtDataKey) throws JsonProcessingException {
        CreateBatchDataCommand command = new CreateBatchDataCommand();
        // 现行接口的总批次是5 先把批次记录创建出来 由定时任务刷新启动批次
        command.setBatchCount(SystemConstants.TOTAL_BATCH_COUNT);
        command.setZtDataKey(needDuijieZtDataKey);
        command.setYears(duijieCommand.getYears());
        command.setMonths(duijieCommand.getMonths());
        command.setNextBatchMap(SystemConstants.NEXT_BATCH_MAP);
        DuijieBatchDto duijieBatchDto = duijieManager.createBatchData(command);

        // 开始对第一批数据
        startByZtDataKeyAndBatchOrder(duijieBatchDto);
    }

    List<Object> getAccSetsListByBuildCommand(BuildCommand buildCommand) {
        // 财务数据库名称
        String cwdb = dataManager.getCwDBName();

        // 如果没指定年份 就取默认年月
        if (buildCommand.getYears() == null) {
            buildCommand.setYears(constants.getDefYears());
        }
        if (buildCommand.getMonths() == null) {
            buildCommand.setMonths(constants.getDefMonths());
        }
        if (buildCommand.getAccModal() == null) {
            String defAccModal = constants.getDefAccModal();
            List<Integer> accModals = null;
            if (defAccModal != null) {
                accModals = new ArrayList<>();
                String[] split = defAccModal.split(",");
                for (String s : split) {
                    accModals.add(Integer.valueOf(s));
                }
            }
            buildCommand.setAccModal(accModals);
        }

        String yearMonth = "" + buildCommand.getYears() +
                (buildCommand.getMonths() < 10 ? ("0" + buildCommand.getMonths()) : buildCommand.getMonths());
//        List<MonthlySettlementDto> allSettledDto = dataManager.getMonthlySettlementByYearMonth(null, yearMonth);
        // 获取哪些账套已经月结 并推送成功的 这次生成跳过这些
        // 获取的是统一社会信用代码
//        List<String> creditCodes = ListUtil.toSingleList(allSettledDto, MonthlySettlementDto::getTYSHXYDM);
//        log.debug(yearMonth + "该年份月份 已月结的账套跳过不生成：" + creditCodes + "");

        List<Object> accSets;

        if (buildCommand.getAccSets() == null) {
            Map<String, Object> buildParams = new HashMap<>();

            String selectSQL = "select acc_set as ACC_SET from " + cwdb + "acc_set where 1=1 and zucode is not null ";
//            if (creditCodes.size() > 0) {
//                selectSQL += " and isnull(zucode,'') not in (:creditCode) ";
//                buildParams.put("creditCode", creditCodes);
//            }
            // 因为有in不能超过1000条数据的问题 这里改成用语句去查已月结的账套
            selectSQL += " and zucode not in (select TYSHXYDM from DJ_ZTYJ where kjqj=:yearMonth and sjjhbz=1) ";
            buildParams.put("yearMonth", yearMonth);
            // 指定模板
            if (buildCommand.getAccModal() != null) {
                selectSQL += " and acc_modal in (:accModal) ";
                buildParams.put("accModal", buildCommand.getAccModal());
            }
            selectSQL += " order by acc_set";
            List<Map<String, Object>> maps = EntityManagerUtil.queryForMapList(entityManager, selectSQL, buildParams);
            accSets = ListUtil.toSingleList(maps, map -> map.get("ACC_SET"));
        } else {
            accSets = buildCommand.getAccSets();
        }
        return accSets;
    }


    void queryTaskIdResultByThread(List<DuijieAsyncDto> duijieAsyncDtos, List<String> taskIds, List<String> subTaskIds) {
        QueryTaskDto queryTaskDto = new QueryTaskDto(subTaskIds);
        List<QueryTaskReturnDto> queryTaskReturnDtos = webExchangeService.queryTask(queryTaskDto);
        if (queryTaskReturnDtos == null) return;// Collections.emptyList();
        // 根据返回结果 更新异步任务表的标志
        // 更新各个数据表相应的数据
        List<SaveTaskIdCommand> saveTaskIdCommands = new ArrayList<>();
        List<SaveSendDataResultCommand> subSaveSendDataResultCommands = new ArrayList<>();
        for (QueryTaskReturnDto returnDto : queryTaskReturnDtos) {
            String taskId = returnDto.getTaskId();
            int sjjhbz = returnDto.getSjjhbz();
            // 匹配异步任务表的数据 获取调用的是哪个接口的任务 serviceCode
            int index = taskIds.indexOf(taskId);
            if (index == -1) {
                continue;
            }
            DuijieAsyncDto duijieAsyncDto = duijieAsyncDtos.get(index);
            Integer accSet = duijieAsyncDto.getAccSet();
            String serviceCode = duijieAsyncDto.getMethodNo();
            Optional<DataApi> optionalDataApi = DataApi.ofOptional(serviceCode);
            if (!optionalDataApi.isPresent()) {
                continue;
            }
            DataApi dataApi = optionalDataApi.get();

            String writeLog;
            if (sjjhbz == SJJHBZ.SUCCESS.getValue() || sjjhbz == SJJHBZ.ERROR.getValue()) {
                log.debug(taskId + "异步任务返回结果！" + returnDto);

                // v1.5.11 处理删除任务 传入的 DATA_KEY 必须全都是已存在的数据 的情况
                if (sjjhbz == SJJHBZ.ERROR.getValue() && isDeleteTaskCanPass(duijieAsyncDto, returnDto)) {
                    sjjhbz = SJJHBZ.SUCCESS.getValue();
                    writeLog = "对方DATA_KEY已不存在，删除成功(" + returnDto.getMessage() + ")";
                } else {
                    writeLog = returnDto.getMessage();
                }

                // 存一条数据进duijie_async 并刷新各中间表的sjjhbz
                saveTaskId(saveTaskIdCommands, taskId, sjjhbz, serviceCode, writeLog, returnDto.getTaskState(), accSet);
                subSaveSendDataResultCommands.add(getSaveSendDataResultCommands(dataApi, sjjhbz, taskId));
            } else {
                // 这里是sjjhbz=3和4 的
                Date createDate = duijieAsyncDto.getCreateDate();
                long daysBetween = DateUtil.getDaysBetween(new Date(), createDate);
                if (daysBetween > SystemConstants.WAIT_DUE_MAX_DAYS) {
                    // 20240717 还在等待结果中 判断是否达到超时时限
                    log.debug(taskId + "达到超时时限");
                    sjjhbz = SJJHBZ.ERROR.getValue();
                    writeLog = "等待超时，超过" + SystemConstants.WAIT_DUE_MAX_DAYS + "天没有返回结果！";

                    // 存一条数据进duijie_async 并刷新各中间表的sjjhbz
                    saveTaskId(saveTaskIdCommands, taskId, sjjhbz, serviceCode, writeLog, returnDto.getTaskState(), accSet);
                    subSaveSendDataResultCommands.add(getSaveSendDataResultCommands(dataApi, sjjhbz, taskId));
                } else {
                    // 20240719 避免重复更新 sjjhbz不一样再更新
                    if (sjjhbz != duijieAsyncDto.getSjjhbz()) {
                        writeLog = returnDto.getMessage();
                        // 存一条数据进duijie_async 并刷新各中间表的sjjhbz
                        saveTaskId(saveTaskIdCommands, taskId, sjjhbz, serviceCode, writeLog, returnDto.getTaskState(), accSet);
                        subSaveSendDataResultCommands.add(getSaveSendDataResultCommands(dataApi, sjjhbz, taskId));
                    }
                }
            }
        }

        // 获取是否有异步任务id不存在第三方那边 更新为异常状态
        List<String> returnTaskIds = ListUtil.toSingleList(queryTaskReturnDtos, QueryTaskReturnDto::getTaskId);
//        log.debug("请求参数：" + queryTaskDto);
        for (String taskId : subTaskIds) {
            if (returnTaskIds.indexOf(taskId) == -1) {
                // 这些是第三方不存在的taskId 设为异常 防止重复获取状态
                // 匹配异步任务表的数据 获取调用的是哪个接口的任务 serviceCode
                int index = taskIds.indexOf(taskId);
                if (index == -1) {
                    continue;
                }
                DuijieAsyncDto duijieAsyncDto = duijieAsyncDtos.get(index);
                // 增加一个超时判断 仅当超过2天的才认为是异常数据 否则可能只是第三方接口没执行完暂时没返回
                Date createDate = duijieAsyncDto.getCreateDate();
                long daysBetween = DateUtil.getDaysBetween(new Date(), createDate);
                if (daysBetween > SystemConstants.WAIT_DUE_MAX_DAYS) {
                    // 20240717 还在等待结果中 判断是否达到超时时限 初步定超过2天为超时
                    log.debug(taskId + "达到超时时限");

                    String serviceCode = duijieAsyncDto.getMethodNo();
                    Optional<DataApi> optionalDataApi = DataApi.ofOptional(serviceCode);
                    if (!optionalDataApi.isPresent()) {
                        continue;
                    }
                    DataApi dataApi = optionalDataApi.get();

                    // 存一条数据进duijie_async
                    saveTaskId(saveTaskIdCommands, taskId, SJJHBZ.ERROR.getValue(), serviceCode, "该taskId不存在", null, duijieAsyncDto.getAccSet());
                    subSaveSendDataResultCommands.add(getSaveSendDataResultCommands(dataApi, SJJHBZ.ERROR.getValue(), taskId));
                }
            }
        }

        if (saveTaskIdCommands.size() > 0) {
            // 存数据进duijie_async
            for (SaveTaskIdCommand command : saveTaskIdCommands) {
                duijieManager.updateAsyncTaskStatus(command);
            }
        }
//        return subSaveSendDataResultCommands;
    }

    private boolean isDeleteTaskCanPass(DuijieAsyncDto duijieAsyncDto, QueryTaskReturnDto returnDto) {
        // 判断错误信息是否为 传入的 DATA_KEY 必须全都是已存在的数据
        String serviceCode = duijieAsyncDto.getMethodNo();
        if (StringUtil.startsWith(serviceCode, "D") && StringUtil.contains(returnDto.getMessage(), "传入的 DATA_KEY 必须全都是已存在的数据")) {
            Optional<DuijieAsyncDto> duijieAsyncById = duijieManager.getDuijieAsyncById(duijieAsyncDto.getId());
            if (duijieAsyncById.isPresent()) {
                DuijieAsyncDto asyncDto = duijieAsyncById.get();
                String content = asyncDto.getContent();
                try {
                    // 判断是否只推了一个DATA_KEY 仅在这种情况下认为是正常
                    Map map = objectMapper.readValue(content, Map.class);
                    List data_keys = (List) map.get("DATA_KEYS");
                    if (data_keys != null && data_keys.size() == 1) {
                        return true;
                    }

                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }
        }
        return false;
    }


    private void saveTaskId(List<SaveTaskIdCommand> saveTaskIdCommands,
                            String taskId, int sjjhbz, String serviceCode, String writeLog, Integer taskState, Integer accSet) {
        SaveTaskIdCommand saveTaskIdCommand = new SaveTaskIdCommand();
        saveTaskIdCommand.setTaskId(taskId);
        saveTaskIdCommand.setServiceCode(serviceCode);
        saveTaskIdCommand.setErrorMsg(writeLog);
        saveTaskIdCommand.setSjjhbz(sjjhbz);
        saveTaskIdCommand.setTaskState(taskState);
        saveTaskIdCommand.setAccSet(accSet);
        saveTaskIdCommands.add(saveTaskIdCommand);
    }

    private SaveSendDataResultCommand getSaveSendDataResultCommands(DataApi dataApi, int sjjhbz, String taskId) {
        // 存到各张数据表的sjjhbz

        SaveSendDataResultCommand command = new SaveSendDataResultCommand();
        command.setDataApi(dataApi);
        command.setSjjhbz(sjjhbz);
        command.setTaskId(taskId);
        return command;
    }


    public List<AccSet> getAccSetsAfterFilter(DuijieCommand duijieCommand, List<AccSet> needDuijieAccSets) {
        List<AccSet> needDuijieAccSetsAfterFilter;
        if (duijieCommand.getNoCheck()) {
            needDuijieAccSetsAfterFilter = needDuijieAccSets;
        } else {
            // 20240725 筛选掉信用代码不为N开头的账套
            needDuijieAccSetsAfterFilter = ListUtil.toListByFilter(needDuijieAccSets,
                    accSet -> StringUtil.startsWith(accSet.getTYSHXYDM(), "N")/* || StringUtil.startsWith(accSet.getTYSHXYDM(), "N2") || StringUtil.startsWith(accSet.getTYSHXYDM(), "N3")*/);
        }
        // v1.5.10 根据账套的canFlag过滤
        if (!duijieCommand.getNoCheckCanFlag()) {
            needDuijieAccSetsAfterFilter = ListUtil.toListByFilter(needDuijieAccSetsAfterFilter, accSet -> accSet.getCanFlag() != null && accSet.getCanFlag());
        }
        return needDuijieAccSetsAfterFilter;
    }


    public ApiDataCollection duijieByAccSetOneBatchNew(DuijieCommand duijieCommand, AccSet accSet, String batchId, List<AbstractApiService<?>> needDuijieApis,
                                                       boolean isMustPushYj) throws JsonProcessingException {
        String needDuijieZtDataKey = accSet.getDATA_KEY();
        DuijieQuery duijieQuery = new DuijieQuery();
        duijieQuery.setZtDataKey(needDuijieZtDataKey);

        duijieQuery.setCreditCode(accSet.getTYSHXYDM());
        duijieQuery.setAccSet(accSet.getAccSet());

        // 设置对接年月
        duijieQuery.setDuijieYears(duijieCommand.getYears());
        duijieQuery.setDuijieMonths(duijieCommand.getMonths());
        // v1.7.2 指定一批推多少条
        duijieQuery.setBatchSize(duijieCommand.getBatchSize() == null ? SystemConstants.DEFAULT_BATCH_SIZE : duijieCommand.getBatchSize());

        // 20240724 先获取该账套的数据 校验没问题再推 若有问题则整张表是异常
        // 20240802 改成只有校验异常的接口不推送 正常的还是照常推送
        // 记录校验异常信息 没异常则没有key key=接口serviceCode value=异常信息
        Map<String, CheckResultDto> checkResultMap = new HashMap<>();
//      数据集合 接口所有数据装在这里
        ApiDataCollection apiDataCollection = new ApiDataCollection();

        // 调用删除接口
        for (AbstractApiService<?> needDuijieApi : needDuijieApis) {
            try {
                needDuijieApi.sendDeleteData(duijieQuery, batchId, webExchangeService);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        Set<String> changedYearMonths = new HashSet<>();
        duijieQuery.setChangedYearMonths(changedYearMonths);

        // v1.6.8 如果是指定一定要推月结 则不管sjjhbz是多少都推 加上指定年月
        if (isMustPushYj) {
            changedYearMonths.add(CommonUtil.getSelectedYearMonth(duijieCommand.getYears(), duijieCommand.getMonths()));
        }

        for (AbstractApiService<?> needDuijieApi : needDuijieApis) {
            // 获取并校验数据
            needDuijieApi.getDataAndCheckResults(checkResultMap, apiDataCollection, duijieQuery);

            // 20240731 若没有指定年份月份 则根据改动过哪些年月的数据 告诉月结要调哪些年月的月结
            if (needDuijieApi instanceof AbstractMonthlyReportApiService) {
                AbstractMonthlyReportApiService<?, ?> monthlyReportApiService = ((AbstractMonthlyReportApiService<?, ?>) needDuijieApi);
                Map<String, ? extends List<?>> map = monthlyReportApiService.getDataFunc().apply(apiDataCollection);
                // 这个map的key即是年月 格式如202402
                changedYearMonths.addAll(map.keySet());
            }
        }

        if (checkResultMap.size() > 0) {
            // 置这个账套为异常状态 存入校验结果表（不卡整个账套了 只卡有问题的接口）
            recordErrorMsgs(checkResultMap, needDuijieZtDataKey, apiDataCollection, needDuijieApis, accSet.getAccSet());
//            log.info("该账套被校验为数据异常，进度：" + countFinal + "/" + total + " 当前账套：" + accSet.getMC());
//            return;
        }

        for (AbstractApiService<?> needDuijieApi : needDuijieApis) {
            DataApi dataApi = needDuijieApi.getDataApi();
            if (checkResultMap.containsKey(dataApi.getServiceCode())) {
                log.debug(dataApi.getDescription() + "该接口存在异常数据，本次跳过不推");
                continue;
            }
            // v1.5.8 有异常的账套不推月结 noCheck=true则照推
            if (!duijieCommand.getNoCheck() && needDuijieApi instanceof ApiMonthlySettlementServiceImpl && checkResultMap.size() > 0) {
                log.debug("本账套有校验异常数据，月结跳过不推送");
                continue;
            }
            try {
                // 调用接口发送数据
                needDuijieApi.sendData(apiDataCollection, duijieQuery, batchId, webExchangeService);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }

        return apiDataCollection;
    }

    // 返回是否有数据推送
    public void startByZtDataKeyAndBatchOrder(DuijieBatchDto duijieBatchDto) throws JsonProcessingException {

        DuijieQuery duijieQuery = new DuijieQuery();
        duijieQuery.setZtDataKey(duijieBatchDto.getZtDataKey());
        // 获取社会统一信用代码
        AccSet accSet = dataManager.getAccSetPO(duijieQuery);
        if (accSet == null) {
            throw new RuntimeException("该账套的ZT_DATA_KEY在DJ_ZTXX中查不到：" + duijieBatchDto.getZtDataKey());
        }
//        duijieQuery.setCreditCode(accSet.getTYSHXYDM());
//        duijieQuery.setAccSet(accSet.getAccSet());
//
//        // 设置对接年月
//        duijieQuery.setDuijieYears(years == null ? constants.getDefYears() : years);
//        duijieQuery.setDuijieMonths(months == null ? constants.getDefMonths() : months);

        log.info("开始按账套对接 当前账套：" + accSet.getMC() + " 批次：" + duijieBatchDto.getBatchOrder() + "/" + SystemConstants.TOTAL_BATCH_COUNT + ", 当前账套：" + accSet.getMC());


        // 查看这个账套已经月结了的年月（暂不判断是否月结）
//        List<String> settledYearMonths = null;

        // 20240720 使用batchId的最后一个部分作为批次标识 batchId组成规则：“【ZT_DATA_KEY】-【时间戳】-【批次标识】”
        String batchKey = StringUtil.substringAfterLast(duijieBatchDto.getBatchId(), "-");
        // 20240807 从工厂类按批次获取接口 只对接该批次下的数据
        List<AbstractApiService<?>> duijieApisByBatchKey = factory.getDuijieApisByBatchKey(batchKey);
        DuijieCommand duijieCommand = new DuijieCommand(duijieBatchDto.getYears(), duijieBatchDto.getMonths(), null);
        // 现在的写法是某个接口的删除和新增在同一批次先后进行 如果这里后来要改成删除放第一批 那就要拆开来
        ApiDataCollection apiDataCollection = duijieByAccSetOneBatchNew(duijieCommand, accSet, duijieBatchDto.getBatchId(), duijieApisByBatchKey, true);

        // 如果一条数据都不用推 则直接启动下一批次
        if (apiDataCollection.isEmpty()) {
            duijieBatchDto.setSjjhbz(SJJHBZ.SUCCESS.getValue());
            duijieBatchDto.setWriteLog("无数据 无需推送");
            duijieBatchDto.setWriteDate(new Date());
            duijieManager.updateNextBatchDataToDuijie(duijieBatchDto.getNextBatchId());
        } else {
            // 最后把该批次sjjhbz更改为3
            duijieBatchDto.setSjjhbz(SJJHBZ.EXECUTING.getValue());
        }
        duijieManager.saveBatchData(duijieBatchDto);
    }

    public <T> void sendNeedDeleteData(String batchId, List<T> needDeleteObjs, DataApi deleteApi, Function<T, String> getDataKeyFunc, Function<T, Integer> getIdFunc, Integer accSet) throws JsonProcessingException {
        // 1000条发送一次
        int count = 0;
        while (count < needDeleteObjs.size()) {
            List<T> subListNeedDeleteVouchers = ListUtil.getSubList(needDeleteObjs, count, count + 1000);
            List<String> needDeletedDataKeys = ListUtil.toSingleList(subListNeedDeleteVouchers, getDataKeyFunc);
            Map<String, Object> deleteMap = new HashMap<>();
            deleteMap.put("DATA_KEYS", needDeletedDataKeys);
            sendMapData(deleteMap, deleteApi, ListUtil.toSingleList(subListNeedDeleteVouchers, getIdFunc), batchId, accSet);

            saveDeletedDataKeys(deleteApi, needDeletedDataKeys);

            count += 1000;
        }
    }

    public void saveDeletedDataKeys(DataApi deleteApi, List<String> needDeletedDataKeys) {
        DeleteDataKeysCommand command = new DeleteDataKeysCommand();
        command.setDataKeys(needDeletedDataKeys);
        command.setServiceCode(StringUtil.replace(deleteApi.getServiceCode(), "D", "W")); // 把接口编号前面的D替换成W就是相应的写入接口
        duijieManager.deleteDuijieDataKeys(command);
    }

    public <T> void sendListData(List<T> dataListObject, DataApi dataApi, List<Integer> ids, String batchId, Integer accSet)  throws JsonProcessingException {
        boolean hasData = dataListObject.size() > 0;
        sendData(dataListObject, dataApi, ids, batchId, hasData, accSet);
    }

    public <K, V> void sendMapData(Map<K, V> dataMapObject, DataApi dataApi, List<Integer> ids, String batchId, Integer accSet)  throws JsonProcessingException {
        boolean hasData = dataMapObject.size() > 0;
        sendData(dataMapObject, dataApi, ids, batchId, hasData, accSet);
    }

    public void sendObjectData(Object dataObject, DataApi dataApi, List<Integer> ids, String batchId, Integer accSet)  throws JsonProcessingException {
        // object类型的 如果传null就是没数据
        boolean hasData = dataObject != null;
        sendData(dataObject, dataApi, ids, batchId, hasData, accSet);
    }

    public void sendData(Object dataObject, DataApi dataApi, List<Integer> ids, String batchId, boolean hasData, Integer accSet) throws JsonProcessingException {
//        String accSetsString = objectMapper.writeValueAsString(object);
        SendDataReturnDto accSetResult = null;
        String errorMsg = null;
        String dataStr = null;

        // 判断如果没有数据 就不推送 但要保存到任务表 （20240726 不保存了）
        if (hasData) {
            try {
                dataStr = objectMapper.writeValueAsString(dataObject);
                accSetResult = webExchangeService.sendData(dataStr, dataApi.getServiceCode());
            } catch (Throwable throwable) {
//            throwable.printStackTrace();
                errorMsg = "接口发送时异常：" + throwable.getMessage();
                log.error("接口发送时异常：", throwable);
            }
        }

        // 根据返回结果 回写异步任务id到表里
        int sjjhbz;
        String taskId;
//        if (!hasData) {
//            // 如果没有数据 就是直接成功
//            sjjhbz = SJJHBZ.SUCCESS.getValue();
//            errorMsg = "无该表数据 无需推送";
//            taskId = null;
//        } else
        // 20240726 现在都是一批过了 无需推送不再记录进异步任务表
        if (hasData) {
            if (accSetResult != null && accSetResult.getIsSuccess()) {
                sjjhbz = SJJHBZ.EXECUTING.getValue();
                errorMsg = SJJHBZ.EXECUTING.getDescription();
                taskId = accSetResult.getTaskId();
            } else {
                sjjhbz = SJJHBZ.ERROR.getValue();
                // 如果出错 自己建一个taskId用于区分
                taskId = "error-" + System.currentTimeMillis();
                if (errorMsg == null && accSetResult != null) {
                    errorMsg = "接口返回异常：" + accSetResult.getMessage();
                }
            }
            // 存一条数据进duijie_async
            SaveTaskIdCommand saveTaskIdCommand = new SaveTaskIdCommand();
            saveTaskIdCommand.setTaskId(taskId);
            saveTaskIdCommand.setServiceCode(dataApi.getServiceCode());
            saveTaskIdCommand.setType(dataApi.getDescription() + "-" + dataApi.getTableName());
            saveTaskIdCommand.setErrorMsg(errorMsg);
            saveTaskIdCommand.setSjjhbz(sjjhbz);
            saveTaskIdCommand.setContent(dataStr);
            saveTaskIdCommand.setBatchId(batchId);
            saveTaskIdCommand.setAccSet(accSet);
            duijieManager.saveAsyncTaskId(saveTaskIdCommand);
            // 存到各张数据表的sjjhbz
            SaveSendDataResultCommand command = new SaveSendDataResultCommand();
            command.setDataApi(dataApi);
            command.setSjjhbz(sjjhbz);
            command.setTaskId(taskId);
            command.setIds(ids);
            duijieManager.saveSendDataResult(command);
        }
//        return null;
    }

    // 记录校验错误日志进数据表
    public void recordErrorMsgs(Map<String, CheckResultDto> errorMsgs, String ztDataKey, ApiDataCollection apiDataCollection, List<AbstractApiService<?>> needDuijieApis, Integer accSet) {
        // 存记录进新的校验结果记录表
        List<DuijieCheck> duijieChecks = new ArrayList<>();
        List<SaveTaskIdCommand> saveTaskIdCommands = new ArrayList<>();
        List<SaveSendDataResultCommand> saveSendDataResultCommands = new ArrayList<>();

        String taskId = null;
        // 首先记录进duijie_async和各中间表
        for (Map.Entry<String, CheckResultDto> entry : errorMsgs.entrySet()) {
            String serviceCode = entry.getKey();
            CheckResultDto checkResultDto = entry.getValue();
            List<String> errorList = checkResultDto.getMessages();
            Optional<DataApi> optionalDataApi = DataApi.ofOptional(serviceCode);
            if (!optionalDataApi.isPresent()) {
                continue;
            }
            DataApi dataApi = optionalDataApi.get();

            int sjjhbz = SJJHBZ.ERROR.getValue();
            // 异常情况 自己建一个taskId用于区分
            taskId = "error-" + System.currentTimeMillis();
            String errorMsg = "校验异常未推送：" + errorList;

            // 存一条数据进duijie_async
            SaveTaskIdCommand saveTaskIdCommand = new SaveTaskIdCommand();
            saveTaskIdCommand.setTaskId(taskId);
            saveTaskIdCommand.setServiceCode(dataApi.getServiceCode());
            String type = dataApi.getDescription() + "-" + dataApi.getTableName();
            saveTaskIdCommand.setType(type);
            saveTaskIdCommand.setErrorMsg(errorMsg);
            saveTaskIdCommand.setSjjhbz(sjjhbz);
            saveTaskIdCommand.setBatchId(ztDataKey);
            saveTaskIdCommand.setAccSet(accSet);
//            duijieManager.saveAsyncTaskId(saveTaskIdCommand);
            saveTaskIdCommands.add(saveTaskIdCommand);
            // 存到各张数据表的sjjhbz
            SaveSendDataResultCommand command = new SaveSendDataResultCommand();
            command.setDataApi(dataApi);
            command.setSjjhbz(sjjhbz);
            command.setTaskId(taskId);
            command.setIds(checkResultDto.getIds());
//            duijieManager.saveSendDataResult(command);
            saveSendDataResultCommands.add(command);

            // 存记录进校验结果记录表
            DuijieCheck duijieCheck = new DuijieCheck();
            duijieCheck.setType(type);
            duijieCheck.setZtDataKey(ztDataKey);
            duijieCheck.setDatetime(new Date());
            duijieCheck.setAcc_set(accSet);
            duijieCheck.setMsg(errorMsg);
            duijieChecks.add(duijieCheck);

        }

        // 因为这套账有校验异常数据导致没有推送 所以没问题的接口数据也要被置为异常状态 提醒维护人员查看
        // 20240802 改成异常不推 正常的还是照推
//        for (AbstractApiService<?> needDuijieApi : needDuijieApis) {
//            DataApi dataApi = needDuijieApi.getDataApi();
//            if (!errorMsgs.containsKey(dataApi.getServiceCode())) {
//                // 存到各张数据表的sjjhbz
//                SaveSendDataResultCommand command = new SaveSendDataResultCommand();
//                command.setDataApi(dataApi);
//                command.setSjjhbz(SJJHBZ.ERROR.getValue());
//                command.setTaskId(taskId);
//                command.setIds(needDuijieApi.getDataIds(apiDataCollection));
//                saveSendDataResultCommands.add(command);
//            }
//        }

        duijieManager.saveAsyncTaskId(saveTaskIdCommands);
        for (SaveSendDataResultCommand command : saveSendDataResultCommands) {
            duijieManager.saveSendDataResult(command);
        }
        duijieManager.saveCheckErrorResults(duijieChecks);

    }


    public void sendFile(SendFileDto sendFileDto, DataApi dataApi, List<Integer> ids) {

        SendDataReturnDto accSetResult = null;
        String errorMsg = null;
        String dataStr = null;


        try {
            accSetResult = webExchangeService.sendFile(sendFileDto, dataApi.getServiceCode());
        } catch (Throwable throwable) {
            errorMsg = "接口发送时异常：" + throwable.getMessage();
            log.error("接口发送时异常：", throwable);
        }


        // 根据返回结果 回写异步任务id到表里
        int sjjhbz;
        String taskId;
        if (accSetResult != null && accSetResult.getIsSuccess()) {
            sjjhbz = SJJHBZ.EXECUTING.getValue();
            errorMsg = SJJHBZ.EXECUTING.getDescription();
            taskId = accSetResult.getTaskId();
        } else {
            sjjhbz = SJJHBZ.ERROR.getValue();
            // 如果出错 自己建一个taskId用于区分
            taskId = "error-" + System.currentTimeMillis();
            if (errorMsg == null && accSetResult != null) {
                errorMsg = "接口返回异常：" + accSetResult.getMessage();
            }
        }


        SaveTaskIdCommand saveTaskIdCommand = new SaveTaskIdCommand();
        saveTaskIdCommand.setTaskId(taskId);
        saveTaskIdCommand.setServiceCode(dataApi.getServiceCode());
        saveTaskIdCommand.setType(dataApi.getDescription() + "-" + dataApi.getTableName());
        saveTaskIdCommand.setErrorMsg(errorMsg);
        saveTaskIdCommand.setSjjhbz(sjjhbz);
        saveTaskIdCommand.setContent(dataStr);
        duijieManager.saveAsyncTaskId(saveTaskIdCommand);
        // 存到各张数据表的sjjhbz
        SaveSendDataResultCommand command = new SaveSendDataResultCommand();
        command.setDataApi(dataApi);
        command.setSjjhbz(sjjhbz);
        command.setTaskId(taskId);
        command.setIds(ids);
        duijieManager.saveSendDataResult(command);
    }


//    public void sendToTestEnv(TestEnvDuijieCommand duijieCommand, List<AbstractApiService<?>> needDuijieApis, AccSet accSet) {
//        String needDuijieZtDataKey = accSet.getDATA_KEY();
//        DuijieQuery duijieQuery = new DuijieQuery();
//        duijieQuery.setZtDataKey(needDuijieZtDataKey);
//
//        duijieQuery.setCreditCode(accSet.getTYSHXYDM());
//        duijieQuery.setAccSet(accSet.getAccSet());
//
//        // 设置对接年月
//        duijieQuery.setDuijieYears(duijieCommand.getYears());
//        duijieQuery.setDuijieMonths(duijieCommand.getMonths());
//
////      数据集合 接口所有数据装在这里
//        ApiDataCollection apiDataCollection = new ApiDataCollection();
//        String batchId = "test-" + System.currentTimeMillis();
//
//        // 调用删除接口
//        for (AbstractApiService<?> needDuijieApi : needDuijieApis) {
//            if (!(needDuijieApi instanceof AbstractPerThousandApiService)) {
//                continue;
//            }
//            AbstractPerThousandApiService<?> apiService = (AbstractPerThousandApiService<?>) needDuijieApi;
//
//            try {
//                // TODO 兼容生成随机数据
//                if (duijieCommand.getOpType() == OpType.DEL.getValue()) {
//                    if (duijieCommand.getIsRandom()) {
//                        Object randomValueObj = CommonUtil.assignRandomValues(apiService);
//                        needDuijieApi.sendDeleteData(Collections.singletonList(randomValueObj), duijieQuery, batchId, testSendwebExchangeService);
//                    } else {
//                        needDuijieApi.sendDeleteData(duijieQuery, batchId, webExchangeService);
//                    }
//                } else {
//                    needDuijieApi.getDataAndCheckResults(new HashMap<>(), apiDataCollection, duijieQuery);
//                    needDuijieApi.sendData(apiDataCollection, duijieQuery, batchId, testSendwebExchangeService);
//                }
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        }
//    }


    /**
     * 根据接口生成该接口的字段的随机字符串 用于调试测试环境
     * @param command
     * @return
     * @throws IllegalAccessException
     * @throws JsonProcessingException
     */
    public String generateRandomJsonString(TestEnvDuijieCommand command) throws IllegalAccessException, JsonProcessingException {
        String serviceCode = command.getServiceCode();
//        Optional<DataApi> optional = DataApi.ofOptional(serviceCode);
//        DataApi dataApi = optional.orElseThrow(() -> new RuntimeException("serviceCode不存在！"));
        DuijieCommand duijieCommand = new DuijieCommand();
        duijieCommand.setServiceCodes(Collections.singletonList(serviceCode));
        List<AbstractApiService<?>> needDuijieApis = factory.getNeedDuijieApis(duijieCommand);

        String creditCode = "{{creditCode}}"; // 信用代码占位符
        if (command.getOpType() == OpType.DEL.getValue()) {
            // 调用删除接口
//            String randomDataKey = CommonUtil.getRandomDataKey();
            String randomDataKey = "44-" + creditCode + "-001";
            Map<String, List<String>> map = Collections.singletonMap("DATA_KEYS", Collections.singletonList(randomDataKey));
            return objectMapper.writeValueAsString(map);

        } else {
            // 新增接口
            Optional<AbstractApiService<?>> optional = needDuijieApis.stream().findFirst();
            AbstractApiService<?> needDuijieApi = optional.orElseThrow(() -> new RuntimeException("serviceCode不存在！"));

            Object obj; // 发送的测试报文
            if (needDuijieApi instanceof ApiSendFileServiceImpl) {// 附件接口
                Map<String, Object> map = new HashMap<>(4);
                map.put("DATA_KEY", "44-" + creditCode + "-file001");
                map.put("TYSHXYDM", creditCode);
                map.put("BUSINESS_DATA_KEY", "44-" + creditCode + "-001");
                map.put("FILE_NAME", CommonUtil.generateRandomValue(String.class));
                obj = map;
            } else if (needDuijieApi instanceof ApiAccSetServiceImpl) { // 账套接口
                String data = String.format("[{\"MC\":\"%s\",\"GDZC_QY_RQ\":null,\"TYSHXYDM\":\"%s\",\"TY_RQ\":null,\"PZH_WS\":1,\"QY_RQ\":\"%s\",\"GDZC_TY_RQ\":null,\"DATA_KEY\":\"%s\"}]",
                        "测试账套", creditCode, "202501", "44-2025-" + creditCode);
                obj = objectMapper.readValue(data, List.class);
            } else {

                Object randomValues = CommonUtil.assignRandomValues(needDuijieApi);
                // 将randomValues转成map，编辑一些字段
                String randomObj = objectMapper.writeValueAsString(randomValues);
                Map<String, Object> map = objectMapper.readValue(randomObj, Map.class);
//            Map<String, Object> map = BeanUtil.beanToMap(randomValues); // 这样会把JsonIgnore的字段也转出来
                // 更新账套KEY
                if (map.containsKey("ZT_DATA_KEY")) {
                    map.put("ZT_DATA_KEY", "44-2025-" + creditCode);
                }
                if (map.containsKey("TYSHXYDM")) {
                    map.put("TYSHXYDM", creditCode);
                }
                if (map.containsKey("DATA_KEY")) {
                    map.put("DATA_KEY", "44-" + creditCode + "-001");
                }
                if (map.containsKey("SSQJ")) {
                    map.put("SSQJ", "202501");
                }
                if (map.containsKey("KJQJ")) {
                    map.put("KJQJ", "202501");
                }
                // 金额字段设成了字符串类型 这里根据字段名称稍作纠正
                for (String key : map.keySet()) {
                    if (StringUtil.endsWith(key, "JE")) {
                        map.put(key, String.valueOf(CommonUtil.generateRandomValue(double.class)));
                    }
                }
                obj = Collections.singletonList(map);
            }
            return objectMapper.writeValueAsString(obj);
        }
    }

    /**
     * 发送到测试环境
     * @param command
     */
    public void sendToTestEnv(TestEnvDuijieCommand command, MultipartFile file) throws IOException {
//        String serviceCode = command.getServiceCode();
        String content = command.getContent();
        // 处理报文中的占位符
        content = StringUtil.replace(content, "{{creditCode}}", command.getCreditCode());

        SendDataReturnDto sendDataReturnDto; // 接口返回结果
        String serviceCode;

        // 获取要对接的serviceCode
        if (StringUtil.equalsIgnoreCase(command.getServiceCode(), "DJ_ZDY") || StringUtil.equalsIgnoreCase(command.getServiceCode(), "DJ_FILE")) {
            // 自定义 直接用customServiceCode
            // 附件 用customServiceCode
            serviceCode = command.getCustomServiceCode();
            // 校验是否调错类型的接口 判断W和D
            if (command.getOpType() == OpType.DEL.getValue() && !StringUtil.startsWithIgnoreCase(serviceCode, "D")) {
                throw new RuntimeException("删除接口必须调用D开头的接口！");
            }
            if (StringUtil.startsWithIgnoreCase(serviceCode, "D") && command.getOpType() != OpType.DEL.getValue()) {
                throw new RuntimeException("D开头的接口请选中删除选项！");
            }
        } else {
            // 用已定义的接口 根据新增和删除判断调哪个接口
            if (command.getOpType() == OpType.DEL.getValue()) {
                // 获取对应的删除接口serviceCode
                DuijieCommand duijieCommand = new DuijieCommand();
                duijieCommand.setServiceCodes(Collections.singletonList(command.getServiceCode()));
                List<AbstractApiService<?>> needDuijieApis = factory.getNeedDuijieApis(duijieCommand);

                Optional<AbstractApiService<?>> optional = needDuijieApis.stream().findFirst();
                AbstractApiService<?> needDuijieApi = optional.orElseThrow(() -> new RuntimeException("serviceCode不存在！"));
                DataApi deleteDataApi = needDuijieApi.getDeleteDataApi();
                AssertUtil.notNull(deleteDataApi, "该接口不支持删除！");
                serviceCode = deleteDataApi.getServiceCode();
            } else {
                serviceCode = command.getServiceCode();
            }
        }
        AssertUtil.hasText(serviceCode, "serviceCode不能为空！");

        // 调接口
        if (StringUtil.equalsIgnoreCase(command.getServiceCode(), "DJ_FILE") && command.getOpType() == OpType.ADD_OR_EDIT.getValue()) {
            // 如果是附件和新增 调sendFile
            AssertUtil.notNull(file, "附件不能为空！");

            // 新增接口
            Map<String, String> map = objectMapper.readValue(content, Map.class);
            SendFileDto sendFileDto = new SendFileDto();
            sendFileDto.setDataKey(map.get("DATA_KEY"));
            sendFileDto.setTyshxydm(map.get("TYSHXYDM"));
            sendFileDto.setBusinessDataKey(map.get("BUSINESS_DATA_KEY"));
            sendFileDto.setFile(file.getBytes());
            sendFileDto.setFileName("FILE_NAME");
            sendFileDto.setFileDateTime(LocalDateTime.now());
            sendDataReturnDto = webExchangeService.sendFile(sendFileDto, serviceCode);
        } else {
            // 其他情况 新增、删除都是sendData
            sendDataReturnDto = webExchangeService.sendData(content, serviceCode);
        }

//        if (StringUtil.equalsIgnoreCase(command.getServiceCode(), "DJ_ZDY")) {
//            // 支持自定义编码
//            serviceCode = command.getCustomServiceCode();
//            if (StringUtil.isEmpty(serviceCode)) {
//                throw new RuntimeException("自定义编码不能为空！");
//            }
//            sendDataReturnDto = webExchangeService.sendData(content, serviceCode);
//        } else {
//
//            DuijieCommand duijieCommand = new DuijieCommand();
//            duijieCommand.setServiceCodes(Collections.singletonList(command.getServiceCode()));
//            List<AbstractApiService<?>> needDuijieApis = factory.getNeedDuijieApis(duijieCommand);
//
//            Optional<AbstractApiService<?>> optional = needDuijieApis.stream().findFirst();
//            AbstractApiService<?> needDuijieApi = optional.orElseThrow(() -> new RuntimeException("serviceCode不存在！"));
//
//
//
//            // 附件接口
//            if (needDuijieApi instanceof ApiSendFileServiceImpl) {
//
//                String customServiceCode = serviceCode = command.getCustomServiceCode();
//                if (StringUtil.isEmpty(customServiceCode)) {
//                    throw new RuntimeException("附件接口编码不能为空！");
//                }
//                if (command.getOpType() == OpType.DEL.getValue()) {
//                    // 删除接口
//                    sendDataReturnDto = webExchangeService.sendData(content, customServiceCode);
//                } else {
//                    if (file == null) {
//                        throw new RuntimeException("附件不能为空！");
//                    }
//
//                    // 新增接口
//                    Map<String, String> map = objectMapper.readValue(content, Map.class);
//                    SendFileDto sendFileDto = new SendFileDto();
//                    sendFileDto.setDataKey(map.get("DATA_KEY"));
//                    sendFileDto.setTyshxydm(map.get("TYSHXYDM"));
//                    sendFileDto.setBusinessDataKey(map.get("BUSINESS_DATA_KEY"));
//                    sendFileDto.setFile(file.getBytes());
//                    sendFileDto.setFileName("FILE_NAME");
//                    sendFileDto.setFileDateTime(LocalDateTime.now());
//                    sendDataReturnDto = webExchangeService.sendFile(sendFileDto, customServiceCode);
//                }
//            } else {
//
//                if (command.getOpType() == OpType.DEL.getValue()) {
//                    // 调用删除接口
//                    DataApi deleteDataApi = needDuijieApi.getDeleteDataApi();
//                    serviceCode = deleteDataApi.getServiceCode();
//                    if (deleteDataApi != null) {
//                        sendDataReturnDto = webExchangeService.sendData(content, deleteDataApi.getServiceCode());
//                    }
//
//                } else {
//                    // 新增接口
//                    serviceCode = needDuijieApi.getDataApi().getServiceCode();
//                    sendDataReturnDto = webExchangeService.sendData(content, needDuijieApi.getDataApi().getServiceCode());
//                }
//            }
//        }


        if (sendDataReturnDto != null) {
//            String sCode = needDuijieApi instanceof ApiSendFileServiceImpl ? command.getCustomServiceCode() : command.getServiceCode();
//            DataApi dataApi = DataApi.ofOptional(serviceCode).get();
            // 记录返回结果
            int sjjhbz;
            String errorMsg, taskId;
            if (sendDataReturnDto.getIsSuccess()) {
                sjjhbz = SJJHBZ.EXECUTING.getValue();
                errorMsg = SJJHBZ.EXECUTING.getDescription();
                taskId = sendDataReturnDto.getTaskId();
            } else {
                sjjhbz = SJJHBZ.ERROR.getValue();
                // 如果出错 自己建一个taskId用于区分
                taskId = "error-" + System.currentTimeMillis();
                errorMsg = "接口返回异常：" + sendDataReturnDto.getMessage();
            }

            // 存一条数据进duijie_async
            SaveTaskIdCommand saveTaskIdCommand = new SaveTaskIdCommand();
            saveTaskIdCommand.setTaskId(taskId);
            saveTaskIdCommand.setServiceCode(serviceCode);
            saveTaskIdCommand.setType("测试" + command.getCreditCode() + "-" + serviceCode);
            saveTaskIdCommand.setErrorMsg(errorMsg);
            saveTaskIdCommand.setSjjhbz(sjjhbz);
            saveTaskIdCommand.setContent(content);
            duijieManager.saveAsyncTaskId(saveTaskIdCommand);
        }
    }


}
